package com.sunwayhorizo.health.business.registries.organization;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import javax.ejb.Stateless;

import org.jboss.seam.Component;
import org.jboss.seam.annotations.Name;

import com.sunwayhorizo.health.business.base.BaseManager;
import com.sunwayhorizo.health.business.dto.ResultsDTO;
import com.sunwayhorizo.health.business.dto.registries.OrganizationDTO;
import com.sunwayhorizo.health.business.registries.organization.query.OrganizationQueryLocal;
import com.sunwayhorizo.health.common.DataTypeUtil;
import com.sunwayhorizo.health.common.DateUtil;
import com.sunwayhorizo.health.common.ListUtil;
import com.sunwayhorizo.health.common.StrUtil;
import com.sunwayhorizo.health.hl7.common.Hl7Exception;
import com.sunwayhorizo.health.hl7.datatypes.AD;
import com.sunwayhorizo.health.hl7.datatypes.BAG_EN;
import com.sunwayhorizo.health.hl7.datatypes.BAG_TEL;
import com.sunwayhorizo.health.hl7.datatypes.CE;
import com.sunwayhorizo.health.hl7.datatypes.ED;
import com.sunwayhorizo.health.hl7.datatypes.II;
import com.sunwayhorizo.health.hl7.datatypes.common.ADXPImpl;
import com.sunwayhorizo.health.hl7.datatypes.common.CSImpl;
import com.sunwayhorizo.health.hl7.datatypes.common.TELImpl;
import com.sunwayhorizo.health.hl7.persistent.RimCoreEntyNames;
import com.sunwayhorizo.health.hl7.rim.ControlAct;
import com.sunwayhorizo.health.hl7.rim.Organization;
import com.sunwayhorizo.health.hl7.rim.Role;
import com.sunwayhorizo.health.hl7.vocabulary.ActCode;
import com.sunwayhorizo.health.hl7.vocabulary.EntityAddrPartType;
import com.sunwayhorizo.health.hl7.vocabulary.EntityAddrUse;
import com.sunwayhorizo.health.hl7.vocabulary.EntityCode;
import com.sunwayhorizo.health.hl7.vocabulary.EntityDeterminer;
import com.sunwayhorizo.health.hl7.vocabulary.EntityIICode;
import com.sunwayhorizo.health.hl7.vocabulary.EntityNameUse;
import com.sunwayhorizo.health.hl7.vocabulary.EntityTelPartType;
import com.sunwayhorizo.health.hl7.vocabulary.EntityTelUse;
import com.sunwayhorizo.health.hl7.vocabulary.ParticipationType;
import com.sunwayhorizo.health.hl7.vocabulary.RoleClass;

/**
 * 
 * @ClassName OrganizationManager <br>
 * @PackageName com.sunwayhorizo.health.business.registries.organization <br>
 * @Description 机构管理类 <br>
 * @Author jinzw <br>
 * @Date 2011-07-14 <br>
 * @Version 1.0 <br>
 * @ModifiedDesc <br>
 * @ModifiedDate <br>
 * @ModifiedBy <br>
 * @Copyright 2010-2020 horizo All Rights Reserved. <br>
 */
@Name("OrganizationManager")
@Stateless
public class OrganizationManager extends BaseManager implements OrganizationManagerLocal
{

    private OrganizationQueryLocal organizationQuery = (OrganizationQueryLocal) Component.getInstance("OrganizationQuery");


    public ResultsDTO newOrganization(OrganizationDTO organizationDTO) throws Hl7Exception
    {
        // 基础数据定义
        String extenID = em.createNativeQuery("select EXTEN_CODE.NEXTVAL from dual").getResultList().get(0).toString();
        CE ce = getDataTypeFactory().newCE(EntityCode.HOSPITAL.toString());
        // 创建一个机构实体
        Organization org = getEntityFactory().newOrganization(ce, EntityDeterminer.INSTANCE, null);
        // 给机构赋值
        converOrganizationToDto(org, organizationDTO);
        // 创建一个机构角色
        Role role = this.getRoleFactory().newRole(RoleClass.IDENT, ce, org, org);
        // 创建ControlAct关系
        ControlAct controlAct = newControlAct(ActCode.HOSPITAL, ParticipationType.SBJ, extenID, role);
        // 持久化
        save(controlAct);
        // 打印日志返回值
        log.info("机构创建成功。实体id=" + org.getEntityId() + "角色id=" + role.getRoleId());
        return getResultsDTO("机构创建成功", true, org.getEntityId().toString());
    }


    public Organization newOrganizationNotPersist(OrganizationDTO organizationDTO) throws Hl7Exception
    {
        // 基础数据定义
        CE ce = getDataTypeFactory().newCE(EntityCode.HOSPITAL.toString());
        // 创建一个机构实体
        Organization org = getEntityFactory().newOrganization(ce, EntityDeterminer.INSTANCE, null);
        // 给机构赋值
        converOrganizationToDto(org, organizationDTO);
        return org;
    }


    @SuppressWarnings("rawtypes")
    public ResultsDTO delOrganization(List orgIds) throws Hl7Exception
    {
        if (ListUtil.isNotEmpty(orgIds))
        {
            boolean isOrg = organizationQuery.findDepartByOrgIds(orgIds);
            if (isOrg)
            {
                return getResultsDTO("机构下面已有科室，该机构不能删除", true, null);
            }
            for (int i = 0; i < orgIds.size(); i++)
            {
                Role role = organizationQuery.findRoleByEntityId((String) orgIds.get(i));
                em.remove(role.getPlayerEntity());
                em.remove(role);
                log.info("删除机构成功。角色id=" + role.getRoleId());
            }
        }
        return getResultsDTO("删除机构成功", true, null);
    }


    @SuppressWarnings("null")
    public ResultsDTO updateOrganization(OrganizationDTO organizationDTO) throws Hl7Exception
    {
        if (organizationDTO == null && StrUtil.isEmpty(organizationDTO.getOrgId()))
            return this.getResultsDTO("机构信息为空，不能修改", true, null);

        Organization org = (Organization) baseQuery.findHl7EntityById(Long.valueOf(organizationDTO.getOrgId()));
        converOrganizationToDto(org, organizationDTO);
        em.merge(org);
        log.info("机构修改成功" + org.getEntityId());
        return this.getResultsDTO("机构信息为空，不能修改", true, org.getEntityId());
    }


    public ResultsDTO findOrganizationList(String orgName, String orgCode) throws Hl7Exception
    {
        List<Role> orgRoleList = organizationQuery.findOrgRoleList(orgName, orgCode);

        List<OrganizationDTO> orgDtoList = new ArrayList<OrganizationDTO>();
        if (ListUtil.isNotEmpty(orgRoleList))
        {
            for (Role role : orgRoleList)
            {
                OrganizationDTO entitiesDTO = converOrganizationDtoToOrgRole(role);
                orgDtoList.add(entitiesDTO);
            }
        }
        log.info("查询出" + orgDtoList.size() + "个机构");
        return this.getResultsDTO("机构查询成功", true, orgDtoList);
    }


    public OrganizationDTO converOrganizationDtoToOrgRole(Role orgRole) throws Hl7Exception
    {
        OrganizationDTO organizationDTO = converOrganizationDtoToOrganization((orgRole.getPlayerEntity() != null ? (Organization) orgRole
            .getPlayerEntity() : null));
        organizationDTO.setRimOrgRoleId(String.valueOf(orgRole.getRoleId()));
        return organizationDTO;
    }


    public void converOrganizationToDto(Organization org, OrganizationDTO organizationDTO) throws Hl7Exception
    {
        if (org == null)
            return;

        // 机构编码
        if (StrUtil.isNotEmpty(organizationDTO.getOrgCode()))
        {
            II ii = DataTypeUtil.getII(root, organizationDTO.getOrgCode(), EntityIICode.ORGANIZATION.toString());
            org.setId(ii);
        }

        // 机构名称
        String[] orgName = new String[1];
        orgName[0] = organizationDTO.getOrgName();
        String placeType[] = { null };
        String placeNameUseCode = EntityNameUse.L.code().toString();
        BAG_EN bagEnName = DataTypeUtil.getBagEN(orgName, placeType, placeNameUseCode);
        org.setName(bagEnName);

        // 机构地址
        String[] addr = new String[2];
        if (!StrUtil.isEmpty(organizationDTO.getOrgAddress()))
        {
            addr[0] = StrUtil.removeNull(organizationDTO.getOrgAddress());
        }
        else
        {
            addr[0] = null;
        }
        if (!StrUtil.isEmpty(organizationDTO.getOrgZip()))
        {
            addr[1] = StrUtil.removeNull(organizationDTO.getOrgZip());
        }
        else
        {
            addr[1] = null;
        }
        String[] addrPart = { EntityAddrPartType.ORGADDRS.code().toString(), EntityAddrPartType.ZIPCODE.code().toString() };
        AD ad = DataTypeUtil.getAD(addr, addrPart, EntityAddrUse.H.code().toString());
        org.setAddr(ad);

        // 联系人
        org.setOrgContact(DataTypeUtil.getST(organizationDTO.getContact()));

        // 机构联系方式
        String[] address = new String[3];
        if (!StrUtil.isEmpty(organizationDTO.getContactTel()))
        {
            address[0] = StrUtil.removeNull(organizationDTO.getContactTel());
        }

        if (!StrUtil.isEmpty(organizationDTO.getOrgTel()))
        {
            address[1] = StrUtil.removeNull(organizationDTO.getOrgTel());
        }

        if (!StrUtil.isEmpty(organizationDTO.getOrgMail()))
        {
            address[2] = StrUtil.removeNull(organizationDTO.getOrgMail());
        }
        String scheme[] = { EntityTelPartType.MOBILE_PHONE.code().toString(), EntityTelPartType.TELCOM_PHONE.code().toString(),
                EntityTelPartType.TELCOM_EMAIL.code().toString() };
        Calendar startTime = GregorianCalendar.getInstance();
        startTime.set(Calendar.HOUR, 9);
        Calendar endTime = startTime;
        endTime.set(Calendar.HOUR, 17);
        Date low = startTime.getTime();
        Date high = endTime.getTime();
        Date useablePeriod[][] = { { low, high }, { low, high }, { low, high } };
        String telUseCode[] = { EntityTelUse.MC.code().toString(), EntityTelUse.WP.code().toString(), EntityTelUse.TMP.code().toString() };
        BAG_TEL bagTel = DataTypeUtil.getBAG_TEL(address, scheme, useablePeriod, telUseCode);
        org.setTelecom(bagTel);

        // 机构简介
        if (StrUtil.isNotEmpty(organizationDTO.getDescription()))
        {
            ED desc = DataTypeUtil.getED(organizationDTO.getDescription());
            org.setDesc(desc);
        }

        // 创建人
        if (StrUtil.isNotEmpty(organizationDTO.getCreateBy()))
        {
            org.setCreatedBy(Long.valueOf(organizationDTO.getCreateBy()));
            org.setCreationDate(DateUtil.getTimestamp(DateUtil.GetDateTime()));
        }
    }


    @SuppressWarnings("rawtypes")
    private OrganizationDTO converOrganizationDtoToOrganization(Organization organization) throws Hl7Exception
    {
        if (organization == null)
            return null;

        OrganizationDTO orgDTO = new OrganizationDTO();

        // 机构RIM 实体id
        orgDTO.setOrgId(organization.getEntityId().toString());

        // 机构名称
        List<RimCoreEntyNames> entyNames = organization.getEntyNamesList();
        if (ListUtil.isNotEmpty(entyNames))
        {
            orgDTO.setOrgName((entyNames.get(0) != null ? entyNames.get(0).getFormatted() : ""));
        }

        // 机构编码
        II ii = organization.getId(EntityIICode.ORGANIZATION);
        orgDTO.setOrgCode((ii != null && ii.extension() != null ? ii.extension().stringValue() : ""));

        // 机构简介
        ED ed = organization.getDesc();
        orgDTO.setDescription((ed != null && !ed.stringValue().equals("<Null:NullFlavor: NI>") ? ed.stringValue() : ""));

        // 机构联系人
        orgDTO.setContact((organization.getOrgContact() != null ? organization.getOrgContact().stringValue() : ""));

        // 机构联系方式
        BAG_TEL tels = organization.getTelecom();
        if (null != tels)
        {
            List mList = tels.toList();
            for (int j = 0; j < mList.size(); j++)
            {
                TELImpl tel = (TELImpl) mList.get(j);
                CSImpl useCode = (CSImpl) tel.use().toSet().iterator().next();
                String use = useCode.code().toString();
                String telName = tel.scheme().code().toString();
                if (telName.equals("<Null:NI>") || telName.equals("<Null:NullFlavor: NI>"))
                {
                    telName = "";
                }
                if (use.equals(EntityTelUse.MC.code().toString()))
                {
                    orgDTO.setContactTel(telName);
                }
                if (use.equals(EntityTelUse.WP.code().toString()))
                {
                    orgDTO.setOrgTel(telName);
                }
                if (use.equals(EntityTelUse.TMP.code().toString()))
                {
                    orgDTO.setOrgMail(telName);
                }
            }
        }
        // 机构地址
        AD addrs = organization.getAddr();
        if (null != addrs)
        {
            List mList = addrs.toList();
            for (int i = 0; i < mList.size(); i++)
            {

                ADXPImpl ad = (ADXPImpl) mList.get(i);
                String type = ad.partType().code().toString();
                String addName = ad.literal().toString();
                if (addName.equals("<Null:NI>") || addName.equals("<Null:NullFlavor: NI>"))
                {
                    addName = "";
                }
                if (type.equals(EntityAddrPartType.ORGADDRS.code().toString()))
                {
                    orgDTO.setOrgAddress(addName);
                }
                if (type.equals(EntityAddrPartType.ZIPCODE.code().toString()))
                {
                    orgDTO.setOrgZip(addName);
                }
            }
        }
        // 创建人
        orgDTO.setCreateBy(String.valueOf(organization.getCreatedBy()));
        return orgDTO;
    }

}
